import {
  AfterViewInit,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  Inject,
  OnInit,
  Input,
  Output,
  PLATFORM_ID,
  Renderer2,
  ViewChild,
  OnChanges,
  SimpleChanges
} from '@angular/core';
import {
  BlockScrollStrategy,
  Overlay,
  OverlayContainer,
  OverlayKeyboardDispatcher,
  OverlayRef
} from '@angular/cdk/overlay';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
import { ESCAPE } from '@angular/cdk/keycodes';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { Store } from '@ngrx/store';
import { AppStoreModule } from '@store/index';
import { ModalTypes } from '@store/reducers/member.reducer';
import { BatchActionsService } from '@store/batch-actions.service';
// import { WINDOW } from '@services/services.module';
import { MemberService } from '@services/member.service';

@Component({
  selector: 'app-wyy-layer-modal',
  templateUrl: './wyy-layer-modal.component.html',
  styleUrls: ['./wyy-layer-modal.component.less'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [trigger('showHide', [
    state('show', style({ transform: 'scale(1)', opacity: 1 })),
    state('hide', style({ transform: 'scale(0)', opacity: 0 })),
    transition('show<=>hide', [animate('0.1s')])
  ])]
})
export class WyyLayerModalComponent implements OnInit, AfterViewInit, OnChanges {
  showModal = 'hide';
  modalTitle = {
    register: '注册',
    loginByPhone: '登录',
    share: '分享',
    like: '收藏',
    default: '登录'
  };
  private readonly isBrowser: boolean;
  private overlayRef: OverlayRef;
  private overlayContainerEle: HTMLElement;
  private readonly scrollStrategy: BlockScrollStrategy;
  @Input() visible = false;
  @Input() showSpin = false;
  @Input() currentModalType = ModalTypes.Default;
  @Output() onLoadSheets = new EventEmitter<void>();
  @ViewChild('modalContainer', { static: false }) private modalRef: ElementRef;
  constructor(
    // @Inject(WINDOW) private win: Window,
    @Inject(DOCUMENT) private doc: Document,
    @Inject(PLATFORM_ID) private platformId: object,
    private store$: Store<AppStoreModule>,
    private overlay: Overlay,
    private elementRef: ElementRef,
    private overlayKeyboardDispatcher: OverlayKeyboardDispatcher,
    private cdr: ChangeDetectorRef,
    private rd: Renderer2,
    private overlayContainerServe: OverlayContainer,
    private memberService: MemberService,
    private batchActionsService: BatchActionsService
  ) {
    this.isBrowser = isPlatformBrowser(this.platformId);
    this.scrollStrategy = this.overlay.scrollStrategies.block();
  }

  ngOnInit() {
    this.createOverlay();
  }
  ngAfterViewInit() {
    this.overlayContainerEle = this.overlayContainerServe.getContainerElement();
    this.listenResizeCenter();
  }
  ngOnChanges(changes: SimpleChanges): void {
    if (changes.visible && !changes.visible.firstChange) {
      this.handleVisibleChange(this.visible);
    }
  }
  private listenResizeCenter() {
    if (this.isBrowser) {
      const modal = this.modalRef.nativeElement;
      const modalSize = this.getHideDomSize(modal);
      this.fixedCenter(modal, modalSize);
      this.rd.listen('window', 'resize', () => this.fixedCenter(modal, modalSize));
    }
  }
  private fixedCenter(modal: HTMLElement, size: { w: number, h: number }) {
    const left = (this.getWindowSize().w - size.w) / 2 + 'px';
    const top = (this.getWindowSize().h - size.h) / 2 + 'px';
    modal.style.left = left;
    modal.style.top = top;
  }
  private getHideDomSize(dom: HTMLElement) {
    return {
      w: dom.offsetWidth,
      h: dom.offsetHeight
    };
  }
  private getWindowSize() {
    return {
      w: window.innerWidth || this.doc.body.clientWidth || this.doc.documentElement.offsetWidth,
      h: window.innerHeight || this.doc.body.clientHeight || this.doc.documentElement.offsetHeight
    };
  }
  private createOverlay() {
    this.overlayRef = this.overlay.create();
    this.overlayRef.overlayElement.appendChild(this.elementRef.nativeElement);
    this.overlayRef.keydownEvents().subscribe(e => this.keyDownListener(e));
  }
  // 按下esc键，关闭弹窗
  private keyDownListener(ev: KeyboardEvent) {
    const keyCode = Number(ev.key);
    if (keyCode === ESCAPE) {
      this.closeModal();
    }
  }
  private handleVisibleChange(visible: boolean) {
    if (visible) {
      this.showModal = 'show';
      // this.scrollStrategy.enable();
      this.overlayKeyboardDispatcher.add(this.overlayRef);
      this.listenResizeCenter();
      this.changePointerEvent('auto');
    } else {
      this.showModal = 'hide';
      // this.scrollStrategy.disable();
      this.overlayKeyboardDispatcher.remove(this.overlayRef);
      this.resizeHandler();
      this.changePointerEvent('none');
    }
    this.cdr.markForCheck();
  }
  private resizeHandler() {
    if (this.modalRef) {
      const modal = this.modalRef.nativeElement;
      const modalSize = this.getHideDomSize(modal);
      this.rd.listen('window', 'resize', () => this.fixedCenter(modal, modalSize));
    }
  }
  private changePointerEvent(type: 'auto' | 'none') {
    if (this.overlayContainerEle) {
      this.overlayContainerEle.style.pointerEvents = type;
    }
  }
  closeModal() {
    this.showModal = 'hide';
    this.batchActionsService.controlModalVisible(false, ModalTypes.LoginByPhone);
  }
}
